use std::rc::Rc;

use actix_web::{
    body::MessageBody, dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}, web, Error, HttpMessage
};
use futures_util::future::{ready, LocalBoxFuture, Ready};

use crate::{base::{errors::AppError, jwt::decode_jwt, Config}};

/// 全局 JWT 拦截中间件
/// 所有请求都需要进行 JWT 校验
/// 
/// @author 张翔宇
/// @since 2025年7月3日
pub struct JwtAuth;

impl<S, B> Transform<S, ServiceRequest> for JwtAuth
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
    S::Future: 'static,
    B: MessageBody + 'static,
{
    type Response = ServiceResponse<B>;
    type Error = Error;
    type InitError = ();
    type Transform = JwtAuthMiddleware<S>;
    type Future = Ready<Result<Self::Transform, Self::InitError>>;

    /// 创建中间件实例
    fn new_transform(&self, service: S) -> Self::Future {
        ready(Ok(JwtAuthMiddleware {
            service: Rc::new(service), // Rc 包装
        }))
    }
}

/// JWT 校验中间件实现
pub struct JwtAuthMiddleware<S> {
    service: Rc<S>,
}

impl<S, B> Service<ServiceRequest> for JwtAuthMiddleware<S>
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
    S::Future: 'static,
    B: MessageBody + 'static,
{
    type Response = ServiceResponse<B>;
    type Error = Error;
    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;

    forward_ready!(service);

    /// 处理每个请求的核心逻辑
    fn call(&self, req: ServiceRequest) -> Self::Future {
        //  获取全局配置（用于 JWT 校验密钥等）
        // ⚠️注意：这里获取的是 web::Data<Config>，不是 Config 本身！！
        let config = match req.app_data::<web::Data<Config>>() {
            Some(cfg) => cfg,
            None => {
                return Box::pin(async move {
                    // 如果没有注入全局配置，返回 500 错误
                    log::error!("未加载到全局配置文件");
                    Err(AppError::Internal.into())
                });
            }
        };

        // let redis_pool = match req.app_data::<web::Data<RedisPool>>() {
        //     Some(pool) => pool.clone(),
        //     None => {
        //         return Box::pin(async move {
        //             log::error!("未加载到 Redis 连接池");
        //             Err(AppError::Internal.into())
        //         });
        //     }
        // };

        // 获取 Authorization 头
        let auth_header = req.headers().get("Authorization").and_then(|h| h.to_str().ok());

        // 检查 Authorization 头部是否为 Bearer token
        if let Some(auth_value) = auth_header {
            if auth_value.starts_with("Bearer ") {
                let token = &auth_value[7..];
                // 验证 JWT
                let claims = match decode_jwt(token, &config.jwt_secret) {
                    Ok(c) => {
                        // 将用户信息插入到请求扩展中
                        req.extensions_mut().insert(c.sub);

                        c
                    },
                    Err(_) => {
                        // token 无效，返回 401
                        return Box::pin(async move {
                            Err(AppError::InvalidToken.into())
                        });
                    }
                };

                // 检查角色权限（异步）
                let service = self.service.clone();
                let path = req.path().to_string();
                let claims_clone = claims.clone();
                // let redis_pool_clone = redis_pool.clone();
                
                return Box::pin(async move {
                    // 获取匹配的权限规则
                    // let required_roles_opt = AuthService::has_permission(redis_pool_clone, &path).await?;

                    // 校验通过，将 claims 注入扩展，便于后续 handler 使用
                    req.extensions_mut().insert(claims_clone.clone());

                    // 角色为 超级管理员 直接放行
                    if claims_clone.roles.iter().any(|r| r == "R_SUPPORT") {
                        return service.call(req).await;
                    }

                    // 没有配置权限或没有所需权限都拒绝
                    // let required_roles = match required_roles_opt {
                    //     Some(roles) => roles,
                    //     None => {
                    //         log::warn!(
                    //             "用户 {} 角色 {:?} 无权限访问 {}，未配置权限",
                    //             claims_clone.sub,
                    //             claims_clone.roles,
                    //             path
                    //         );
                    //         return Err(AppError::Forbidden("没有所需权限".to_string()).into());
                    //     }
                    // };

                    // // 检查用户是否拥有所需角色
                    // let has_permission = required_roles
                    //     .iter()
                    //     .any(|required_role| claims_clone.roles.contains(required_role));

                    // if !has_permission {
                    //     log::warn!(
                    //         "用户 {} 角色 {:?} 无权限访问 {}，需要角色 {:?}",
                    //         claims_clone.sub,
                    //         claims_clone.roles,
                    //         path,
                    //         required_roles
                    //     );
                    //     return Err(AppError::Forbidden("没有所需权限".to_string()).into());
                    // }

                    // 有权限，放行
                    service.call(req).await
                });
            }
        }

        // 没有 token 或格式不对，返回 401
        Box::pin(async move {
            Err(AppError::MissingToken.into())
        })
    }
}